<?php
/**
 * FileRepo.php
 *
 * @copyright   2023 thingsworld.com.cn - All Rights Reserved
 * @link        http://thingsworld.com.cn/
 * @author      stiffer.chen <chenl@thingsworld.com.cn>
 * @created     2023-02-16 04:12:19
 * @modified    2023-02-16 04:12:19
 *
 */

namespace App\Repositories;

use App\Library\Logger;

class FileRepo
{
    /**
     * .json => application/json
     * .png => image/png
     * .gif => image/gif
     * .jpg => image/jpeg
     * .bmp => image/bmp
     * .xls => application/vnd.ms-excel
     * .xlsx => application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
     * .ppt => application/vnd.ms-powerpoint
     * .pptx => application/vnd.openxmlformats-officedocument.presentationml.presentation
     * .doc => application/msword
     * .docx => application/vnd.openxmlformats-officedocument.wordprocessingml.document
     * .txt => text/plain
     *
     * @throws \Exception
     */
    public static function upload()
    {
        $logger = new Logger('file_upload');
        $file = request()->file('attachment');
        if (empty($file)) {
            throw new \Exception('请上传文件');
        }
        $byteSize = $file->getSize();
        $kbSize = round($byteSize / 1024, 2);
        $fileOriginName = $file->getClientOriginalName();
        // 文件名
        $fileName = self::getNameWithNoSuffix($fileOriginName);
        // 后缀
        $fileSuffix = self::getSuffix($fileOriginName);
        $mimeType = $file->getMimeType() ?? '';
        $types = self::allowTypes();
        $allowFileType = array_keys($types);
        if (!in_array($fileSuffix, $allowFileType)) {
            throw new \Exception('文件类型错误');
        }
        $trueMimeType = $types[$fileSuffix];
        if (!$trueMimeType || $trueMimeType != $mimeType) {
            // throw new \Exception(t('file.error_mime'));
        }
        $saveName = $fileName . '_' . date('YmdHis') . '.' . $fileSuffix;
        if (in_array($fileSuffix, self::imageTypes())) {
            $returnDir = self::createImagePath();
            $returnPath = $returnDir . '/' . $saveName;
            $file->move($returnDir, $saveName);
            return [
                'name' => $saveName,
                'path' => $returnPath,
                'url' => env('APP_URL') . '/' . $returnPath,
                'size' => $kbSize . 'kb'
            ];
        }

        $returnDir = self::createFilePath();
        $returnPath = $returnDir . '/' . $saveName;
        $file->move($returnDir, $saveName);
        return [
            'path' => $returnPath
        ];
    }

    private static function createImagePath(): string
    {
        $imagePath = 'images/' . date('Y/m/d');
        $imageAbsolutePath = public_path() . '/' . $imagePath;
        if (is_dir($imageAbsolutePath)) {
            return $imagePath;
        }
        @mkdir($imageAbsolutePath, 0777, true);
        return $imagePath;
    }

    private static function createFilePath(): string
    {
        $filePath = 'files/' . date('Y/m/d');
        $fileAbsolutePath = public_path() . '/' . $filePath;
        if (is_dir($fileAbsolutePath)) {
            return $filePath;
        }
        @mkdir($fileAbsolutePath, 0777, true);
        return $filePath;
    }

    /**
     * 获取后缀
     *
     * @param string $str
     * @return string
     */
    private static function getSuffix(string $str): string
    {
        $str = trim($str);
        if (empty($str)) {
            return '';
        }
        $strArr = explode('.', $str);
        if (count($strArr) == 1) {
            return '';
        }
        return strtolower($strArr[count($strArr) - 1]);
    }

    /**
     * 获取不含后缀文件名
     *
     * @param string $str
     * @return string
     */
    private static function getNameWithNoSuffix(string $str): string
    {
        $str = trim($str);
        if (empty($str)) {
            return '';
        }
        $strArr = explode('.', $str);
        if (count($strArr) == 1) {
            return $str;
        }
        $strNameArr = array_slice($strArr, 0, count($strArr) - 1);
        return implode('.', $strNameArr);
    }

    private static function allowTypes()
    {
        return [
            'json' => 'application/json',
            'png' => 'image/png',
            'gif' => 'image/gif',
            'jpg' => 'image/jpg',
            'jpeg' => 'image/jpg',
            'bmp' => 'image/bmp',
            'xls' => 'application/vnd.ms-excel',
            'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
            'ppt' => 'application/vnd.ms-powerpoint',
            'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
            'doc' => 'application/msword',
            'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            'txt' => 'text/plain',
            'pdf' => 'application/pdf'
        ];
    }

    private static function imageTypes()
    {
        return [
            'png', 'gif', 'jpg', 'jpeg', 'bmp'
        ];
    }
}